package com.jackeysun.util

import java.text.SimpleDateFormat
import java.util.*
import kotlin.math.max
import kotlin.math.min

fun Date.format(pattern: String = "yyyy-MM-dd HH:mm:ss"): String =
    SimpleDateFormat(pattern).format(this)

fun String.toDate(pattern: String): Date =
    SimpleDateFormat(pattern).parse(this)

/**
 * 两个日期只差
 * @return 返回两个日期之间的天数
 */
fun Date.toDays(date: Date = Date()): Int {
    val DAY_OF_MILLIS = (24 * 60 * 60 * 1000).toLong()
    return this.toTimeDiff(date, DAY_OF_MILLIS)
}

/**
 * 两个日期只差
 * @return 返回两个日期之间的小时
 */
fun Date.toHours(date: Date = Date()): Int {
    val HOUR_OF_MILLIS = (60 * 60 * 1000).toLong()
    return this.toTimeDiff(
        date, HOUR_OF_MILLIS,
        startHour = this.getMinDate(date).getHour(),
        endHour = this.getMaxDate(date).getHour()
    )
}

/**
 * 两个日期只差
 * @return 返回两个日期之间的分钟
 */
fun Date.toMinutes(date: Date = Date()): Int {
    val MINUTE_OF_MILLIS = (60 * 1000).toLong()
    return this.toTimeDiff(
        date,
        MINUTE_OF_MILLIS,
        startHour = this.getMinDate(date).getHour(),
        endHour = this.getMaxDate(date).getHour(),
        startMinute = this.getMinDate(date).getMinute(),
        endMinute = this.getMaxDate(date).getMinute()
    )
}

/**
 * 两个日期只差
 * @return 返回两个日期之间的秒数
 */
fun Date.toSeconds(date: Date = Date()): Int {
    val SECOND_OF_MILLIS = 1000.toLong()
    return this.toTimeDiff(
        date, SECOND_OF_MILLIS,
        startHour = this.getMinDate(date).getHour(),
        endHour = this.getMaxDate(date).getHour(),
        startMinute = this.getMinDate(date).getMinute(),
        endMinute = this.getMaxDate(date).getMinute(),
        startSecond = this.getMinDate(date).getSecond(),
        endSecond = this.getMaxDate(date).getSecond()
    )
}


fun Date.toTimeDiff(
    date: Date = Date(),
    unit: Long,
    startHour: Int = 0,
    startMinute: Int = 0,
    startSecond: Int = 0,
    endHour: Int = 0,
    endMinute: Int = 0,
    endSecond: Int = 0,
): Int {
    val maxDate = max(this.time, date.time)
    val minDate = min(this.time, date.time)
    val cal1 = Calendar.getInstance().apply { timeInMillis = minDate }
    cal1[Calendar.HOUR_OF_DAY] = startHour
    cal1[Calendar.MINUTE] = startMinute
    cal1[Calendar.SECOND] = startSecond
    val cal2 = Calendar.getInstance().apply { timeInMillis = maxDate }
    cal2[Calendar.HOUR_OF_DAY] = endHour
    cal2[Calendar.MINUTE] = endMinute
    cal2[Calendar.SECOND] = endSecond
    return ((cal2.timeInMillis - cal1.timeInMillis).div(unit)).toInt()
}

fun Date.getYEAR(): Int =
    Calendar.getInstance().apply { time = this@getYEAR }.get(Calendar.YEAR)

fun Date.getMONTH(): Int =
    Calendar.getInstance().apply { time = this@getMONTH }.get(Calendar.MONTH).plus(1)

fun Date.getDayOfMonth(): Int =
    Calendar.getInstance().apply { time = this@getDayOfMonth }.get(Calendar.DAY_OF_MONTH)

fun Date.getDayOfYear(): Int =
    Calendar.getInstance().apply { time = this@getDayOfYear }.get(Calendar.DAY_OF_YEAR)

fun Date.getWeekOfMonth(): Int =
    Calendar.getInstance().apply { time = this@getWeekOfMonth }.get(Calendar.WEEK_OF_MONTH)

fun Date.getDayOfWeek(): Int =
    Calendar.getInstance().apply { time = this@getDayOfWeek }.get(Calendar.DAY_OF_WEEK)

/**
 * 24小时制
 */
fun Date.getHour(): Int =
    Calendar.getInstance().apply { time = this@getHour }.get(Calendar.HOUR_OF_DAY)

fun Date.getMinute(): Int =
    Calendar.getInstance().apply { time = this@getMinute }.get(Calendar.MINUTE)

fun Date.getSecond(): Int =
    Calendar.getInstance().apply { time = this@getSecond }.get(Calendar.SECOND)

private fun Date.getMaxDate(date: Date): Date =
    if (this.time > date.time) {
        this
    } else {
        date
    }

private fun Date.getMinDate(date: Date): Date =
    if (this.time > date.time) {
        date
    } else {
        this
    }